Release 10.1A: OpenEdge Development:
Progress Dynamics Advanced Development


Repository Manager API

These are a few of the most useful methods in the Repository Manager API. The principal body of code for the Repository Manager is in the include file ry/app/ryrepmngrp.i.

cacheObjectOnClient

The function cacheObjectOnClient checks if the requested object exists in the client-side cache. If the requested object is not in the cache, it is retrieved from the Repository and placed in the cache. This function returns a logical value signifying the success of the operation.

The cacheObjectOnClient() function ensures that all the requested objects, their contained instances, their associated master objects, and all related information is placed in the cache.

When cacheObjectOnClient is called, it first checks to see if the requested object is cached. If it is, then the relevant record is positioned to and nothing further happens. If the record does not exist in the cache, then the function must retrieve the data from the Repository and place it into the cache. If the Repository database is connected, then cacheObjectOnClient runs bufferFetchObject. This performs the actual retrieval and puts the objects into a cache using putObjectInCache.

If the Repository database is not connected locally, then the function runs doServerRetrieval. This procedure runs serverFetchObject on the AppServer. serverFetchObject runs bufferFetchObject and puts the information into temp-tables, which are then returned to the caller. doServerRetrieval then calls putObjectInCache, which ensures that the objects are in the cache. The last thing that cacheObjectOnClient does is to do a FIND on the requested record in the cache so that it is AVAILABLE to the caller.

The cacheObjectOnClient function takes the following INPUT parameters:

The methods bufferFetchObject, serverFetchObject, doServerRetrieval, and putObjectInCache should be considered private to the Repository Manager. You should not normally run these directly.

Functions used to retrieve cache table buffer handles

All operations that must use the cache information use the one set of temp-tables where all cached data resides. There is a set of functions to return the buffer handles of the tables in the cache. These are:

With the except of getCacheObjectBuffer and getCacheClassBuffer, these functions take no INPUT parameters. Each returns the HANDLE of the requested buffer.

getCacheObjectBuffer() takes as an input parameter an optional object instance ID and returns the buffer handle of the cache_Object table. If the input value is a non-null instance ID, the function finds the relevant record in the cache_Object table before returning the buffer handle. This is important because it means that, with an instance ID, you can get back an AVAILABLE buffer handle to the record in the cache. This saves having to do FIND-FIRST() to position to the desired record yourself.

getCacheClassBuffer() takes as an input parameter the name of a class (the object type code) and returns the buffer handle of the ttClass temp-table. With this you can read class attributes without starting from a particular object. If you pass in a single, valid class name, the buffer that it returns points to the ttClass record that corresponds to that class. If the class name passed in to the function does not yet exist in the ttClass table portion of the client cache, the function retrieves it from the Repository. You can also pass in either an asterisk ('*') to represent all classes or a comma-separated list of class names, and all the valid classes in the list are retrieved. However, in this case no ttClass record is positioned to at the end of the function, since there is no single right record to find.

Using the API to retrieve class attributes and values

To be able to access the attributes for a class, you must first get the handle of the attribute buffer. The ttClass buffer handle that getCacheClassBuffer returns is the handle of the record for the class in the ttClass table, not the handle of the attribute table for the class. The buffer handle of the attribute temp-table is stored in the classBufferHandle field of the ttClass record.

This code sample shows how you can retrieve all of the attributes and their default values for a given class, for example, the dynamic SDO or DynSDO. The first call is to the function getCacheClassBuffer in the global handle of the Repository Manager. This ensures that the DynSDO class is in the client cache, and returns the handle of the ttClass buffer. If the data is not already there, it is retrieved from the server. The function does a FIND of the correct record in the cache when it is done, as shown:

DEFINE VARIABLE httClassBuffer        AS HANDLE    NO-UNDO. 
DEFINE VARIABLE hClassAttributeBuffer AS HANDLE    NO-UNDO. 
DEFINE VARIABLE iFieldCount           AS INTEGER   NO-UNDO. 
DEFINE VARIABLE cAttributeName        AS CHARACTER NO-UNDO. 
DEFINE VARIABLE cClassAttributeValue  AS CHARACTER NO-UNDO. 
ASSIGN httClassBuffer = DYNAMIC-FUNCTION("getCacheClassBuffer":U IN  
         gshRepositoryManger, INPUT "DynSDO"). 

The classBufferHandle field holds the handle of the buffer handle for the specific dynamic class table for the class’s attributes, in this case cache_DynSDO, as shown:

ASSIGN hClassAttributeBuffer =  
    httClassBuffer:BUFFER-FIELD("classBufferHandle"):BUFFER-VALUE. 

The variable hClassAttributeBuffer now points to the cache_DynSDO buffer. Now you can get all the attribute values for the class. The INITIAL value of the field represents the default value of each attribute for this class, as shown:

DO iFieldCount = 1 TO hClassAttributeBuffer:NUM-FIELDS: 
    ASSIGN cAttributeName =  
               hClassAttributeBuffer:BUFFER-FIELD(iFIeldCount):NAME 
           cClassAttributeValue =  
               hClassAttributeBuffer:BUFFER-FIELD(iFIeldCount):INITIAL 
           .  
/* Process the attribute values */ 
END. 

One important thing to keep in mind is that with only one set of buffers to access everything in the cache, you must be aware that records can go out of scope. So, if you find a cache_Object record and then run an object based on it, chances are that by the time the run statement returns to your procedure, the cache_Object record you were positioned to is no longer current. This is mainly because the prepareInstance function (described later) is run for every SmartObject, and it interacts with the cache_Object records. It is very easy to reposition the cache_Object record back to the desired record. If you pass getCacheObjectBuffer() a valid Record Identifier (instance ID), it repositions the cache_Object buffer to the correct record. Alternatively, you can use your own set of defined buffers to give you additional buffers whose records won’t be changed out from under you.

Accessing Repository data without the cache

If you would rather not use the cache, as would be the case in application design tools, then when making calls from a development tool, you can call serverFetchObject directly. This procedure returns the requested information in table form. This means that you are guaranteed to get the data as it is in the Repository at any given moment. However, what you lose is the caching. A full description of serverFetchObject and other calls that access the data more directly is beyond the scope of this chapter. You should study the code in ry/app/ryrepmngrp.i if you are building a development tool that you feel must use these internal calls. Be aware that serverFetchObject, for example, has a complex calling sequence that includes a large number of TABLE-HANDLES, each one for a separate temp-table for attribute data related to a particular class of object.

Do not use the cache if you want to use the information for design purposes in a tool. Running cacheObjectOnClient() returns the object in unaggregated form: each result code is separated. If you want to design with aggregated data, then you would need to run this procedure or clear the cache with every call.

You can also use the serverFetchObject procedure when you want to retrieve Repository data for external use, for example, in a tool that does some form of analysis or reporting of the Repository data.


Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095